package com.example.service.user.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.example.config.ProjectProperties;
import com.example.dto.request.user.UserSettingsRequestDTO;
import com.example.exception.db.UpdateException;
import com.example.exception.user.UnavailableUsernameException;
import com.example.mapper.UserMapper;
import com.example.pojo.User;
import com.example.service.user.UserSettingsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;


/**
 * @author Lexin Huang
 */
@Slf4j
@Service
public class UserSettingsServiceImpl extends ServiceImpl<UserMapper, User> implements UserSettingsService {
    private final String FILE_RESOURCE_PATH_SEPARATOR;

    private final String AVATAR_DIRECTORY_PATH;

    private final String[] SUPPORTED_AVATAR_TYPES;

    private final String AVATAR_URL_PREFIX;

    private final String DEFAULT_AVATAR_URL;


    public UserSettingsServiceImpl(ProjectProperties projectProperties) {
        this.AVATAR_URL_PREFIX = projectProperties.getUserInfo().getAvatar().getUrlPrefix();
        this.AVATAR_DIRECTORY_PATH = projectProperties.getUserInfo().getAvatar().getDirectoryPath();
        this.DEFAULT_AVATAR_URL = projectProperties.getUserInfo().getAvatar().getDefaultAvatarUrl();
        this.SUPPORTED_AVATAR_TYPES = projectProperties.getUserInfo().getAvatar().getSupportedTypes();
        this.FILE_RESOURCE_PATH_SEPARATOR = projectProperties.getFile().getResourcePathSeparator();
    }

    /**
     * 1#Bug 待修复
     * 删除原有头像, 上传新的头像, 并更新数据库都可能发生异常, 异常发生时, 数据库要回滚, 文件也得恢复
     */
    @Transactional(rollbackFor = Exception.class)
    @Deprecated
    @Override
    public void replaceAvatar(User user, MultipartFile image) throws Exception {

        String original = user.getPortraitPath();
        List<String> imagesUrl = upload(new MultipartFile[]{image});
        String current = imagesUrl.get(0);
        user.setPortraitPath(current);
        if (!updateById(user)) {
            deleteFileByUrl(current);
            throw new UpdateException("上传头像失败!");
        }
        removeAvatarIfNotDefault(original);
    }


    @Override
    public void updatePassword(User user) {
        if (!updateById(user)) {
            throw new UpdateException("出错了, 修改密码失败! 请稍后再试!");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void modifyProfile(User userToUpdate, UserSettingsRequestDTO requestDTO) {
        if (!userToUpdate.getUsername().equals(requestDTO.getUsername())) {
            checkIfNameIsAvailable(requestDTO.getUsername());
        }
        if (!updateById(userToUpdate)) {
            throw new UpdateException("出错了, 更新个人资料失败! 请稍后再试!");
        }
    }

    private void checkIfNameIsAvailable(String username) {
        if (null == username || null != baseMapper.getByUsername(username)) {
            throw new UnavailableUsernameException("用户名称为 " + username + " 的用户已存在!");
        }
    }

    @Override
    public String getDirectoryPathSeparator() {
        return this.FILE_RESOURCE_PATH_SEPARATOR;
    }

    @Override
    public String getFileUrlPrefix() {
        return this.AVATAR_URL_PREFIX;
    }

    @Override
    public String getStorageDirectoryPath() {
        return this.AVATAR_DIRECTORY_PATH;
    }

    @Override
    public boolean needToRemove(String avatarUrl) {
        return !this.DEFAULT_AVATAR_URL.equals(avatarUrl);
    }

    @Override
    public String[] getSupportedFileTypeNames() {
        return this.SUPPORTED_AVATAR_TYPES;
    }
}
